package graphics.system;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.lwjgl.opengl.GL20;

import tools.Help;
import tools.Point;
public class Shader {
	private int shaderprogram;
	public void load(String fname) {
		FileInputStream fstream;
		String vertsrc = "";
		String fragsrc = "";
		boolean vmode = true;
		try {
			fstream = new FileInputStream(fname);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String line;
			while ((line = br.readLine()) != null) {
				if (line.contains("FRAGMENT")) {
					vmode = false;
				}
				else {
					if (line.contains("//")) {
						line = line.substring(0, line.indexOf("//"));
					}
					if (vmode)
						vertsrc += line + "\n";
					else
						fragsrc += line + "\n";
				}
			}
		} catch (FileNotFoundException e) {
			System.out.println("Shaderfile not found: " + fname + " !!!");
			return;
		} catch (IOException e) {
			e.printStackTrace();
		}
		/*
		 * Help.p(vertsrc); Help.p(" ");Help.p(" "); Help.p(fragsrc);
		 */
		this.shaderprogram = GL20.glCreateProgram();
		int shader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
		GL20.glShaderSource(shader, vertsrc);
		GL20.glCompileShader(shader);
		int status = GL20.glGetShader(shader, GL20.GL_COMPILE_STATUS);
		if (status != 1) {
			String errors = GL20.glGetShaderInfoLog(shader, 2000);
			System.out.println("Error while compiling shader(Vertex): " + fname + "! log:\n" + errors);
		}
		GL20.glAttachShader(shaderprogram, shader);
		shader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
		GL20.glShaderSource(shader, fragsrc);
		GL20.glCompileShader(shader);
		status = GL20.glGetShader(shader, GL20.GL_COMPILE_STATUS);
		if (status != 1) {
			String errors = GL20.glGetShaderInfoLog(shader, 2000);
			System.out.println("Error while compiling shader(Fragment): " + fname + "! log:\n" + errors);
		}
		GL20.glAttachShader(shaderprogram, shader);
		GL20.glLinkProgram(shaderprogram);
		status = GL20.glGetProgram(shaderprogram, GL20.GL_LINK_STATUS);
		if (status != 1) {
			String errors = GL20.glGetProgramInfoLog(shaderprogram, 2000);
			System.out.println("Error while linking shader: " + fname + "! log:\n" + errors);
		}
	}
	public void enable() {
		GL20.glUseProgram(shaderprogram);
	}
	public void disable() {
		GL20.glUseProgram(0);
	}
	public void setParamf(String param, float f) {
		int id = GL20.glGetUniformLocation(shaderprogram, param.subSequence(0, param.length()));
		GL20.glUniform1f(id, f);
	}
	public void setParam2f(String param, Point p) {
		int id = GL20.glGetUniformLocation(shaderprogram, param.subSequence(0, param.length()));
		GL20.glUniform2f(id, p.x, p.y);
	}
	public void setParam2f(String param, float x, float y, float z) {
		int id = GL20.glGetUniformLocation(shaderprogram, param.subSequence(0, param.length()));
		GL20.glUniform3f(id, x, y, z);
	}
	public void setParami(String param, int i) {
		int id = GL20.glGetUniformLocation(shaderprogram, param.subSequence(0, param.length()));
		GL20.glUniform1i(id, i);
	}
	public void delete() {
		GL20.glDeleteProgram(shaderprogram);
	}
}
